import { Controller } from "egg";
import { createHash } from "crypto";
import { isNil, isEmpty } from "lodash";
import { mapKeys, camelCase } from "lodash";
import { spawn } from "child_process";
import { resolve as pathResolve } from "path";
import * as log4js from "log4js";
import * as moment from "moment";
const loginParamRule = {
  account: { type: "string", trim: true },
  password: { type: "string", trim: true },
  captcha: { type: "string", required: false, trim: true }
};

log4js.configure({
  appenders: {
    server: {
      type: "multiFile",
      base: pathResolve(`/root/MobileFrameworkBackend/logs/`),
      property: "date",
      extension: ".log"
    }
  },
  categories: {
    default: { appenders: ["server"], level: "debug" }
  }
});
const logger = log4js.getLogger();
logger.addContext("date", moment().format("YYYY-MM-DD"));

export default class GlobalController extends Controller {
  public async login(ctx) {
    const { account, password } = ctx.request.body;
    try {
      ctx.validate(loginParamRule);
    } catch (e) {
      this.ctx.response.status = 422;
      this.ctx.body = { success: false, message: "参数错误" };
      return;
    }
    // const error = ctx.validate(loginParamRule);

    // console.log(error)
    /*if(!isEmpty(error)){
          // this.ctx.body = { success: false, message: "参数错误" };
          ctx.body = ctx.app.renderBody({
              statusType: ctx.app.statusType.paramsError,
              error,
          });
          return;
      }*/
    const encryptedPassword = createHash("md5")
      .update(password)
      .digest("hex");

    const userInstance = await ctx.model.User.find({ where: { account } });

    if (isNil(userInstance) || isEmpty(userInstance)) {
      ctx.response.status = 404;
      this.ctx.body = { success: false, message: "用户不存在" };
      return;
    }

    if (encryptedPassword !== userInstance.password) {
      ctx.response.status = 404;
      this.ctx.body = { success: false, message: "用户名或密码错误" };
      return;
    }

    try {
      this.ctx.session.profile = userInstance;
      this.ctx.session.failedTimes = 0;
      this.ctx.body = { success: true, session: userInstance };
    } catch (e) {
      ctx.response.status = 500;
      this.ctx.body = { success: false, message: "系统错误" };
      this.app.logger.error("系统错误：\n%s", e);
    }
  }

  public async logout(ctx) {
    // session 库写异常处理未加，后续加上
    ctx.session.profile = undefined;
    ctx.body = { success: true };
  }

  public async getStore(ctx) {
    // const { profile, menu, flatMenu } = ctx.session;
    const userInstance = await ctx.model.User.find({
      where: { account: "root" }
    });
    const { id: user_id } = userInstance;
    const roleUserInstance = await ctx.model.RoleUser.find({
      where: { user_id }
    });
    const { role_id } = roleUserInstance;
    const { type } = await ctx.model.Role.find({
      where: { id: role_id }
    });
    const roleFuncInstances = await ctx.model.RoleFunc.findAll({
      where: { role_id }
    });
    const menus = await Promise.all(
      roleFuncInstances.map(r =>
        ctx.model.Func.find({
          where: { id: r.func_id }
        })
      )
    );
    const dicInstances = await ctx.model.Dic.findAll();
    const orgInstances = await ctx.model.Org.findAll();
    const roleInstances = await ctx.model.Role.findAll();
    const appInstances = await ctx.model.App.findAll();
    ctx.body = {
      success: true,
      data: {
        session: { ...userInstance.get(), type, roleId: role_id },
        menus: menus.filter(r => r),
        dictionary: [
          ...dicInstances.map(r =>
            mapKeys(r.get(), (_v, k) => {
              return camelCase(k);
            })
          ),
          ...orgInstances.map(r => {
            const row = r.get();
            return {
              tableName: "t_org",
              colName: "org_id",
              key: row.id,
              value: row.org_name
            };
          }),
          ...roleInstances.map(r => {
            const row = r.get();
            return {
              tableName: "t_role",
              colName: "role_id",
              key: row.id,
              value: row.role_name
            };
          }),
          ...appInstances.map(r => {
            const row = r.get();
            return {
              tableName: "t_app",
              colName: "app_id",
              key: row.id,
              value: row.app_name
            };
          })
        ]
      }
    };
  }

  public async getCaptcha(ctx) {
    ctx.body = {};
  }

  public async gitUpdater(ctx) {
    const options = { stdio: ["pipe", "pipe", "pipe", "ipc"] };
    const script = pathResolve(
      `/root/MobileFrameworkBackend/shell/gitUpdater.sh`
    );
    await new Promise((res, rej) => {
      let child = spawn("bash", [script], options);
      child.stdout.on("data", data => {
        ctx.logger.info(data.toString());
      });

      child.stderr.on("data", data => {
        ctx.logger.error(data.toString());
      });
      child.on("close", res);
      child.on("error", rej);

      setTimeout(res, 60000);
    });

    ctx.body = { success: true };
  }
}
